// 进行URL转义用，不用管
function percentEncode(str) {

    var s = encodeURI(str);

    return s
        .replace(/ /g, "%20")
        .replace(/\//g, "%2F")
        .replace(/\+/g, "%20")
        .replace(/\*/g, "%2A")
        .replace(/\%7E/g, "~")
        .replace(/\=/g, "%3D")
        .replace(/\&/g, "%26")
        .replace(/\:/g, "%253A")
}

// 生成公共参数个和请求HOST
function getCommonParamsAndHost() {
    var now = new Date()
    var year = now.getUTCFullYear()
    var month = now.getUTCMonth() + 1
    var day = now.getUTCDate()
    var hour = now.getUTCHours()
    var minute = now.getUTCMinutes()
    var second = now.getUTCSeconds()

    year = String(year)
    month = month < 10 ? "0" + String(month) : String(month)
    day = day < 10 ? "0" + String(day) : String(day)
    hour = hour < 10 ? "0" + String(hour) : String(hour)
    minute = minute < 10 ? "0" + String(minute) : String(minute)
    second = second < 10 ? "0" + String(second) : String(second)

    params = {
        "Format": "JSON",
        "Version": "2018-01-20",
        "AccessKeyId": "LTAI4GDJZYHdgyDNgDnVp2nC",
        "SignatureMethod": "HMAC-SHA1",
        "Timestamp": year + "-" + month + "-" + day + "T" + hour + ":" + minute + ":" + second + "Z",
        "SignatureVersion": "1.0",
        "SignatureNonce": String(Math.floor(Math.random() * 1_0000) + 1),
        "RegionId": "cn-shanghai"
    }

    return [params, "https://iot.cn-shanghai.aliyuncs.com/"]
}

// 生成签名，需要使用外部库Crypto-JS
function getSignature(params, accessKeySecret) {
    var lis = new Array()

    for (var k in params) {
        lis.push([k, params[k]])
    }
    lis.sort(function (a, b) {
        if (a[0] < b[0]) return -1
        else if (a[0] == b[0]) return 0
        else return 1;
    })

    // console.log(lis)

    sig = ""
    for (var i = 0; i < lis.length; ++i) {
        sig = sig + (i == 0 ? "" : "&") + lis[i][0] + "=" + lis[i][1]
    }
    sig = "GET&" + percentEncode("/") + "&" + percentEncode(sig)

    console.log(sig)

    sig = CryptoJS.enc.Base64.stringify(CryptoJS.HmacSHA1(sig, accessKeySecret + "&"))
    // console.log(sig)
    return sig
}

// 查询设备当前状态
function queryDevicePropertyStatus() {
    const accessKeySecret = "j1EiOpZuBmzH7fC9dS1wz31kzlTCoI"
    var tmp = getCommonParamsAndHost()
    var params = tmp[0]
    var host = tmp[1] + "?"

    params["Action"] = "QueryDevicePropertyStatus"
    params["DeviceName"] = "ESP32_MicroPython"
    params["ProductKey"] = "a15NNbDLsRb"

    var sig = getSignature(params, accessKeySecret)
    params["Signature"] = sig
    for (var k in params) {
        host = host + k + "=" + params[k] + "&"
        console.log(k + "   " + params[k])
    }
    return host
}

/**
 * 
 * @param {int} msg 暂定msg为正整数
 * 
 * 返回发布数据所要调用的API的URL
 * API返回的数据是JSON格式，如果调用成功，返回数据会包含Success=true，否则，Success=false
 * 详见https://help.aliyun.com/document_detail/69793.html?spm=a2c4g.11186623.6.873.4f066afdDgkDqk
 * 
 * msg的作用：
 * 暂定msg=1让开发板在OLED上显示当前的时间和日期，msg=2让开发板在OLED上显示传感器的数据 
 */
function publishData(msg) {
    const accessKeySecret = "j1EiOpZuBmzH7fC9dS1wz31kzlTCoI"
    var tmp = getCommonParamsAndHost()
    var params = tmp[0]
    var host = tmp[1] + "?"

    params["Action"] = "Pub"
    params["MessageContent"] = encodeURIComponent(btoa(String(msg))) // CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(String(msg)))
    params["ProductKey"] = "a15NNbDLsRb"
    params["TopicFullName"] = encodeURIComponent("/a15NNbDLsRb/ESP32_MicroPython/user/operation")
    params["Qos"] = 1
    
    var sig = getSignature(params, accessKeySecret)
    params["Signature"] = sig
    for (var k in params) {
        host = host + k + "=" + params[k] + "&"
        console.log(k + "   " + params[k])
    }
    return host
}

/**
 * 
 * @param {int} angle [-90, 90]
 */
function controlServo(angle) {
    const accessKeySecret = "j1EiOpZuBmzH7fC9dS1wz31kzlTCoI"
    var tmp = getCommonParamsAndHost()
    var params = tmp[0]
    var host = tmp[1] + "?"

    params["Action"] = "Pub"
    params["MessageContent"] = encodeURIComponent(btoa(String(angle))) // CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(String(msg)))
    params["ProductKey"] = "a15NNbDLsRb"
    params["TopicFullName"] = encodeURIComponent("/a15NNbDLsRb/ESP32_MicroPython/user/servo")
    params["Qos"] = 1
    
    var sig = getSignature(params, accessKeySecret)
    params["Signature"] = sig
    for (var k in params) {
        host = host + k + "=" + params[k] + "&"
        console.log(k + "   " + params[k])
    }
    return host
}
